package cn.jsu.oj.judgment.net.starter;


import cn.jsu.oj.judgment.config.ResourceConfig;
import cn.jsu.oj.judgment.net.JudgeClient;
import cn.jsu.oj.judgment.net.netHandler.JudgeClientHandler;
import cn.jsu.oj.judgment.parsing.JudgeStarterAnn;
import cn.jsu.oj.judgment.pojo.checkinfo.JudgeAbstractCheckInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 判题机任务调度验证启动器
 *
 */
@Slf4j
@Component("judgeVerifyStarter")
@JudgeStarterAnn(starter = 97)
public class JudgeVerifyStarter implements JudgeStarter{

    @Autowired
    ScheduledThreadPoolExecutor judgeSchedule;

    private static final Integer JUDGE_ACTIVE_SLEEP = ResourceConfig.getConfigInteger("net.judge.active.sleep");

    private static final String PASSWORD = ResourceConfig.getConfigString("net.client.judge.connect.password");

    private static final Integer JUDGE_VERIFY_SLEEP = ResourceConfig.getConfigInteger("net.judge.verify.sleep");

    private static final Integer REAL_PORT = ResourceConfig.getConfigInteger("net.judge.real.port");

    private boolean isRun = false;

    private ScheduledFuture<?> scheduledFuture;


    @Override
    public void start() {
        if(this.isRun){
            return;
        }
        this.isRun = true;
        this.scheduledFuture =judgeSchedule.scheduleAtFixedRate(() -> {
            if (ServiceStarter.judgeActiveSign && !ServiceStarter.judgeVerifySign) {
                log.info("----------正在验证任务调度......");
                try {
                    //获取本地端口
                    int port = getPort();
                    JudgeClientHandler.channel.writeAndFlush(new JudgeAbstractCheckInfo(PASSWORD,port,100).serialize());
                } catch (Exception e) {
                    log.error(e.getLocalizedMessage(),e);
                }
            }
            else if (ServiceStarter.judgeVerifySign && ServiceStarter.judgeActiveSign) {
                log.info("----------任务调度验证成功......");
                log.info("----------等待判题任务触发......");
                judgeSchedule.setRemoveOnCancelPolicy(true);
                Objects.requireNonNull(this.scheduledFuture
                        , "----------结果写回调度未来为空，任务中断失败......")
                        .cancel(true);
                this.isRun = false;
            }
        },0, JUDGE_VERIFY_SLEEP, TimeUnit.MILLISECONDS);
    }

    private int getPort() {
        InetSocketAddress socketAddress = (InetSocketAddress)JudgeClient.channelFuture.channel().localAddress();
        return socketAddress.getPort();
    }
}
